package com.load.ctrls.imp;

import java.io.Serializable;
import java.net.Authenticator;
import java.util.*;

import com.database.daos.*;
import com.database.objects.*;
import com.load.batch.BatchExecutor;
import com.load.ctrls.*;
import com.load.factories.IssueFactory;
import com.load.utils.*;

public class LoadTrackCtrl implements ILoadTrackCtrl, Serializable {

	private static final long serialVersionUID = 7917485491056277749L;

	private IProjectDao projectDao;

	private IElementDao elementDao;

	private IIssueDao issueDao;

	private IContributionCtrl contributionCtrl;

	@Override
	public void load(Project project, BatchExecutor executor) throws Exception {
		if (executor.requiresProxy()) {
			Authenticator.setDefault(new SimpleAuthenticator(executor.getProxyName(), executor.getProxyPassword()));
		}

		executor.setStatus("Configurating Load ...");

		TrackerRepository repository = project.getTrackerRepository();
		configureRepository(repository, project.getName());
		saveProjectAndDevelopers(project);

		executor.setTotalLoad(repository.getNumIssues());

		List<Map<KeyIssue, String>> issuesMap = repository.getTextIssues();
		for (Map<KeyIssue, String> issueMap : issuesMap) {
			try {
				Issue issue = buildIssue(project, issueMap);
				if (issue != null) {
					issueDao.saveElement(issue);
					executor.addSuccessLoaded("Loading Issue: " + issue.getNumber() + "...");
				}
			} catch (Exception e) {
				e.printStackTrace();
				executor.addErrorsLoaded("Error Loading Issue " + issueMap.get(KeyIssue.NUMBER));
			}
		}

		for (Developer developer : project.getDevelopers()) {
			List<Element<?, ?>> issues = elementDao.findIssuesByDeveloper(developer);
			contributionCtrl.calculateContributions(developer, project.getTrackerRepository(), issues);
		}
	}

	private Issue buildIssue(Project project, Map<KeyIssue, String> issueMap) {
		Long number = Long.valueOf(issueMap.get(KeyIssue.NUMBER));
		Issue issue = elementDao.getIssueByNumber(project, number);
		if (issue == null) {
			issue = IssueFactory.createIssue(project, issueMap);
			elementDao.saveElement(issue);
		}
		return issue;
	}

	private void configureRepository(TrackerRepository repository, String name) throws Exception {
		repository.constructUrl(name);
		repository.constructTextIssues();
	}

	private void saveProjectAndDevelopers(Project project) {
		Project projectDB = projectDao.getByName(project.getName());
		if (projectDB != null) {
			projectDB.setTrackerRepository(project.getTrackerRepository());
			project.clone(projectDB);
		}

		List<Map<KeyIssue, String>> issues = project.getTrackerRepository().getTextIssues();
		for (Map<KeyIssue, String> issue : issues) {
			String name = issue.get(KeyIssue.DEVELOPER);
			if (name != null && !name.equals("")) {
				project.addDeveloper(new Developer(name, project));
			}
		}
		projectDao.saveElement(project);
	}

	public void setProjectDao(IProjectDao projectDao) {
		this.projectDao = projectDao;
	}

	public void setElementDao(IElementDao elementDao) {
		this.elementDao = elementDao;
	}

	public void setIssueDao(IIssueDao issueDao) {
		this.issueDao = issueDao;
	}

	public void setContributionCtrl(IContributionCtrl contributionCtrl) {
		this.contributionCtrl = contributionCtrl;
	}

}